package com.zhang.spring.boot.mongo;

import com.zhang.data.mongo.core.MongoUtil;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.util.ConcurrentReferenceHashMap;

import java.lang.reflect.Method;
import java.util.Map;

public class QueryExecutorMethodInterceptor implements MethodInterceptor {

    private final Map<Method, QueryMethodInvoker> invocationMetadataCache = new ConcurrentReferenceHashMap<>();

    private final MongoRepository mongoRepository;

    private final Class<?> domainClazz;

    private MongoUtil mongoUtil;

    public QueryExecutorMethodInterceptor(MongoRepository mongoRepository,MongoUtil mongoUtil, Class domainClazz) {
        this.mongoRepository = mongoRepository;
        this.mongoUtil = mongoUtil;
        this.domainClazz=domainClazz;
    }

    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Method method=methodInvocation.getMethod();
        QueryMethodInvoker invocationMetadata = invocationMetadataCache.get(method);

        if (invocationMetadata == null) {
            invocationMetadata = new QueryMethodInvoker(method,this.mongoRepository,this.mongoUtil,this.domainClazz);
            invocationMetadataCache.put(method, invocationMetadata);
        }
        return invocationMetadata.invoke(methodInvocation.getArguments());
    }
}
